/*
 * Copyright (c) 2020 - present, Inspur Genersoft Co., Ltd.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *       http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package io.iec.edp.caf.commons.exception.diagnostic.initializer;

import io.iec.edp.caf.commons.exception.diagnostic.exception.DataSourceCreationException;
import io.iec.edp.caf.commons.exception.diagnostic.exception.RedisConfigException;
import io.iec.edp.caf.commons.runtime.CafEnvironment;
import io.iec.edp.caf.commons.utils.StringUtils;
import io.iec.edp.caf.multicontext.support.YamlReader;
import lombok.var;
import org.springframework.context.ApplicationContextInitializer;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.core.env.Environment;

import java.util.List;
import java.util.Map;

/**
 * @author wangyandong
 * @date 2021/09/26 17:23
 * @email wangyandong@inspur.com
 */
public class RedisInitializer implements ApplicationContextInitializer {
    /**
     * Initialize the given application context.
     *
     * @param applicationContext the application to configure
     */
    @Override
    public void initialize(ConfigurableApplicationContext applicationContext) {
        Environment env = applicationContext.getEnvironment();
        //这里因为配置中心会走两遍，cloud走一遍，boot走一遍，cloud里过来，此Property被赋值，boot里不被赋值，cloud和boot里的env不是同一个
        var loaded = env.getProperty("caf.config.client");
        if(loaded==null){
            //如果是不启用Redis，或者 不强制检查密码，直接返回
            if ("false".equals(env.getProperty("redis.enabled","true")) ||
                    !"true".equals(env.getProperty("redis.requirepass","false"))) {
                return;
            }

            //分两段进行检查：1. spring.redis   2. cache-configuration
            //spring.redis.password 或 spring.redis.redisson.config
            String fileName = env.getProperty("spring.redis.redisson.config");
            if(StringUtils.isEmpty(env.getProperty("spring.redis.password")) &&
                    StringUtils.isEmpty(fileName)){
                throw new RedisConfigException("未设置Redis密码！");
            }else if(!StringUtils.isEmpty(fileName)){
                //配置了redisson.config
                YamlReader yamlReader = new YamlReader(fileName);
                String password = yamlReader.getValueByKey("singleServerConfig.password", null);
                if(StringUtils.isEmpty(password)){
                    password = yamlReader.getValueByKey("clusterServersConfig.password", null);
                }
                if(StringUtils.isEmpty(password)){
                    throw new RedisConfigException("未设置Redis密码！");
                }
            }

            //cache-configuration
            //为兼容配置中心使用场景，不直接读application.yaml，而是直接从environment中读取
            //YamlReader yamlReader = new YamlReader(fileName);
            //List<Map> managers = yamlReader.getValueByKey("caching-configuation.redisManagers", null);
            //if(managers==null)
            //    return;
            //for(Map map:managers){
            //    if(!map.containsKey("password"))
            //        throw new RedisConfigException("Redis密码不能为空，请设置密码后重试！");
            //}
            String Name_Format = "caching-configuration.redisManagers[%s].name";
            String Password_Format = "caching-configuration.redisManagers[%s].name";
            int index =0;
            String keyOfName = String.format(Name_Format,index);
            String keyOfPass = String.format(Password_Format,index);
            while(!StringUtils.isEmpty(env.getProperty(keyOfName))){
                if(StringUtils.isEmpty(env.getProperty(keyOfPass)))
                    throw new RedisConfigException("未设置Redis密码！");
                index ++;
                keyOfName = String.format(Name_Format,index);
                keyOfPass = String.format(Password_Format,index);
            }
        }

    }
}
